<?php

namespace app\api\controller;

use app\common\controller\Api;
use addons\heycustoms\library\Alipay\AlipayGateway;
use app\admin\model\HeyInfo;
use app\admin\model\HeyPayRecord;
use app\admin\model\Order;
use fast\Random;
use fast\Http;
use think\Config;

/**
 * 拉取下属商场系统数据
 */
class HeyPayCustoms extends Api
{

    protected $noNeedLogin = '*';
    protected $noNeedRight = '*';

    private $api_version = '1.0';
    private $country_list = false;

    private $errmsg = '';
    private $trans_count = 0;
    private $trans_time = 0;

    private $save_data = [];
    private $model;

    private $admin_id;

    public function _initialize()
    {
        parent::_initialize();
    }

    /**
     *
     * @return [type]
     */
    private function _init() {

    }

    /**
     * 推送到支付宝
     * @return [type] [description]
     */
    public function customs_push(){
        $order_id = $this->request->request('order_id');
        $return = $this->customs_push_one($order_id);
        if ($return) {
            $this->success($this->errmsg,$this->errmsg);
        }else{
            $this->error($this->errmsg,$this->errmsg);
        }
    }

    /**
     * 查询报关单状态
     * @return [type] [description]
     */
    public function customs_query(){
        $record_id = $_REQUEST['record_id'];
        $return = $this->customs_query_one($record_id);
        if ($return) {
            $this->success($this->errmsg,$this->errmsg);
        }else{
            $this->error($this->errmsg,$this->errmsg);
        }
    }

    /**
     * 根据订单号报关一条支付单
     * @param  [type] $order_id [description]
     * @return [type]           [description]
     */
    private function customs_push_one($order_id){
        // $admin_id = $this->request->request('admin_id');

        $order_info = Order::find($order_id);
        $this->admin_id = $order_info['admin_id'];
        $pay_config = HeyInfo::getPayConfig($this->admin_id);
        
        if (!$order_info) {
            $this->errmsg = '订单数据未查到';
            return false;
        }
        if (!$order_info['pay_sn']) {
            $this->errmsg = '支付单无数据';
            return false;
        }

        if ($order_info['pay_scope'] == 'alipay') {
            if ($pay_config && $pay_config['alipay']) {

                if (!$pay_config['alipay']['alipay_ent_code'] || !$pay_config['alipay']['alipay_ent_code']) {
                    $this->errmsg = '订单所属商户报关参数未设置';
                    return false;
                }

                $param = [
                    'out_request_no' => $order_info['out_trade_no'],
                    'trade_no' => $order_info['pay_sn'],
                    'merchant_customs_code' => $pay_config['alipay']['alipay_ent_code'],
                    'merchant_customs_name' => $pay_config['alipay']['alipay_ent_name'],
                    'amount' => $order_info['order_fee'],
                    'customs_place' => $pay_config['alipay']['alipay_customs'],
                    'buyer_name' => $order_info['buyer_name'],
                    'buyer_id_no' => $order_info['buyer_id_no'],
                ];
                // var_dump($param);exit;
                /*支付宝报关*/
                $alipayGateway = new AlipayGateway($pay_config['alipay']);
                $alipay_res = $alipayGateway->acquire($param);

                /*准备数据*/
                $this->alipay_model_data('push' ,$param, $order_info);

                if ($alipay_res && $alipay_res['is_success'] == 'T') {
                    $alipay_respose = $alipay_res['response']['alipay'];
                    if ($alipay_respose['result_code'] == 'SUCCESS') {
                        // 业务正常 //
                        $extra = [
                            'verify_depart' => $alipay_respose['trade_no'],    // 支付单据号
                            'depart_trade_no' => $alipay_respose['alipay_declare_no'],   // 支付宝报关流水号
                        ];

                        $this->set_response('submitted', 'PUSH_SUCCESS', '已推送到支付宝', $extra);

                    }elseif ($alipay_respose['result_code'] == 'FAIL') {
                        // 业务出错 //
                        $alipay_respose['detail_error_code'];   // 错误码
                        $alipay_respose['detail_error_des'];    // 错误描述
                        $this->set_response('failure', $alipay_respose['detail_error_code'], $alipay_respose['detail_error_des']);
                    }
                    if (isset($alipay_respose['identity_check']) && $alipay_respose['identity_check'] == 'T') {
                        // 身份校验匹配成功 //
                        $this->set_buyer_status(true);
                    }elseif (isset($alipay_respose['identity_check']) && $alipay_respose['identity_check'] == 'F') {
                        // 身份校验不匹配 //
                        $this->set_buyer_status(false);
                    }

                }elseif ($alipay_res && $alipay_res['is_success'] == 'F') {
                    // 请求失败或者接入数据错误 //
                    $alipay_res['error'];    // 错误代码
                    $this->set_response('except', $alipay_res['error'], '支付宝推送错误:'.$alipay_res['error'], '', '');
                        
                }else{
                    // 系统错误 //
                    $this->set_response('except', 'API_EXCEPT', '支付宝接口异常', '', '');
                }
                /*保存数据*/
                if ($flag = $this->model_save($param, $order_info)) {
                    return true; 
                }else{
                    $this->errmsg = '数据保存异常';
                    return false; 
                }

            }else{
                $this->errmsg = '支付宝参数配置不正确';
                return false; 
            }
        }elseif ($order_info['scope'] == 'wechat') {
            $this->errmsg = '微信支付报关未接入';
            return false;    
        }else{
            $this->errmsg = '订单支付方式无法进行报关';
            return false;
        }
    }

    /**
     * 根据订单号报关一条支付单
     * @param  [type] $order_id [description]
     * @return [type]           [description]
     */
    private function customs_query_one($record_id){
        // $admin_id = $this->request->request('admin_id');

        $record_info = HeyPayRecord::find($record_id);
        $admin_id = $record_info['admin_id'];
        $pay_config = HeyInfo::getPayConfig($admin_id);
        
        if (!$record_info) {
            $this->errmsg = '订单数据未查到';
            return false;
        }

        if ($record_info['pay_scope'] == 'alipay') {

            if (!$record_info['out_request_no']) {
                $this->errmsg = '支付单无数据';
                return false;
            }

            if ($pay_config && $pay_config['alipay']) {

                if (!$pay_config['alipay']['alipay_ent_code'] || !$pay_config['alipay']['alipay_ent_code']) {
                    $this->errmsg = '订单所属商户报关参数未设置';
                    return false;
                }

                $param = [
                    'out_request_no' => $record_info['out_request_no'],
                ];
                // var_dump($param);exit;
                /*支付宝报关*/
                $alipayGateway = new AlipayGateway($pay_config['alipay']);
                $alipay_res = $alipayGateway->query($param);

                /*准备数据*/
                $this->alipay_model_data('query' ,$param, $record_info);

                if ($alipay_res && $alipay_res['is_success'] == 'T') {
                    $alipay_respose = $alipay_res['response']['alipay'];

                    if ($alipay_respose['result_code'] == 'SUCCESS') {
                        if (!isset($alipay_respose['records'])) {
                            $this->errmsg = '未查询到此单';
                            return false;
                        }
                        // 只拿第一条
                        $customs_declare = isset($alipay_respose['records']['customs_declare'][0])?$alipay_respose['records']['customs_declare'][0]:$alipay_respose['records']['customs_declare'];

                        // 业务正常 //
                        $customs_declare['trade_no'];   // 支付单据号
                        $customs_declare['customs_place'];   // 海关编号。
                        $customs_declare['merchant_customs_code'];   // 商户在海关备案的编号
                        $customs_declare['merchant_customs_name'];   // 商户海关备案的名称
                        $extra = [
                            'out_request_no' => $customs_declare['out_request_no'],   // 商户端报关请求号
                            'customs_status' => $customs_declare['status'],   // 报关单当前的状态
                            'customs_time' => $customs_declare['last_modified_time'],   // 状态最后更新时间
                            'customs_memo' => implode('|', $customs_declare['memo']),   // 返回备注
                            'customs_code' => $customs_declare['customs_code'],    // 海关返回回执 2：支付单新增申报成功 120：海关入库 小于0的数字：表示处理异常回执
                            'customs_info' => $customs_declare['customs_info'],   // 海关结果描述信息
                            'customs_return_time' => $customs_declare['customs_return_time'],   // 海关返回回执的时间
                        ];

                        if ($customs_declare['status'] == 'ws') {
                            $this->set_response('processing', 'PROCESSING_WS', '等待发送海关', $extra);
                        }elseif ($customs_declare['status'] == 'sending') {
                            $this->set_response('processing', 'PROCESSING_SENDING', '已提交发送海关', $extra);
                        }elseif ($customs_declare['status'] == 'succ') {
                            $this->set_response('success', 'SUCCESS', $customs_declare['customs_info'], $extra);
                            // if ($customs_declare['customs_code'] == '2') {
                            //     $this->set_response('success', 'SUCCESS_ADDED', $customs_declare['customs_info'], $extra);
                            // }elseif ($customs_declare['customs_code'] == '120') {
                            //     $this->set_response('success', 'SUCCESS_FILLED', $customs_declare['customs_info'], $extra);
                            // }elseif ($customs_declare['customs_code'] < 0) {
                            //     $this->set_response('failure', 'CUSTOM_FAILURE', $customs_declare['customs_info'], $extra);
                            // }else{
                            //     $this->set_response('except', 'CUSTOM_EXCEPT', $customs_declare['customs_info'], $extra);
                            // }
                        }

                    }elseif ($alipay_respose['result_code'] == 'FAIL') {
                        // 业务出错 //
                        $alipay_respose['detail_error_code'];   // 错误码
                        $alipay_respose['detail_error_des'];    // 错误描述
                        $this->set_response('failure', $alipay_respose['detail_error_code'], $alipay_respose['detail_error_des']);
                    }

                    /*用户身份信息申报*/
                    if (isset($alipay_respose['identity_check']) && $alipay_respose['identity_check'] == 'T') {
                        // 身份校验匹配成功 //
                        $this->set_buyer_status(true);
                    }elseif (isset($alipay_respose['identity_check']) && $alipay_respose['identity_check'] == 'F') {
                        // 身份校验不匹配 //
                        $this->set_buyer_status(false);
                    }

                }elseif ($alipay_res && $alipay_res['is_success'] == 'F') {
                    // 请求失败或者接入数据错误 //
                    $alipay_res['error'];    // 错误代码
                    $this->set_response('except', $alipay_res['error'], '支付宝报关错误:'.$alipay_res['error']);
                        
                }else{
                    // 系统错误 //
                    $this->set_response('except', 'API_EXCEPT', '支付宝接口异常');
                }
                /*保存数据*/
                if ($flag = $this->model_save($param, $record_info)) {
                    return true; 
                }else{
                    $this->errmsg = '数据保存异常';
                    return false; 
                }

            }else{
                $this->errmsg = '支付宝参数配置不正确';
                return false; 
            }
        }elseif ($record_info['scope'] == 'wechat') {
            $this->errmsg = '微信支付报关未接入';
            return false;    
        }else{
            $this->errmsg = '订单支付方式无法进行报关';
            return false;
        }
    }

    /**
     * 使用订单号加四位随机数生成
     * @param  [type] $order_sn [description]
     * @return [type]           [description]
     */
    private function alipay_generate_no($order_sn){
        return $order_sn.mt_rand(1000,9999);
    }

    private function alipay_model_data($type ,$param, $data_info) {
        $data_arr = [];
        if ($type == 'push') {
            $data_arr = [
                'admin_id' => $data_info['admin_id'],
                'order_id' => $data_info['order_id'],
                'order_sn' => $data_info['order_sn'],
                'pay_sn' => $data_info['pay_sn'],
                'pay_scope' => $data_info['pay_scope'],
                'buyer_name' => $data_info['buyer_name'],
                'buyer_mobile' => $data_info['buyer_mobile'],
                'order_fee' => $data_info['order_fee'],
                'request_param' => json_encode($param, JSON_UNESCAPED_UNICODE),
                'out_request_no' => isset($param['out_request_no'])?$param['out_request_no']:'',

                'record_time' => time(),
                // 'buyer_status' => $data_info['buyer_status'],
                // 'response_code' => $data_info['response_code'],
                // 'response_msg' => $data_info['response_msg'],
                // 'record_status' => $data_info['record_status'],
                // 'verify_depart' => $data_info['verify_depart'],
                // 'depart_trade_no' => $data_info['depart_trade_no'],
            ];
        }elseif ($type == 'query') {
            $data_arr = [
                'id' => $data_info['id'],
                'order_id' => $data_info['order_id'],
                // 'customs_status' => $data_info['customs_status'],
                // 'customs_memo' => $data_info['customs_memo'],
                // 'customs_time' => $data_info['customs_time'],
                // 'customs_code' => $data_info['customs_code'],
                // 'customs_info' => $data_info['customs_info'],
                // 'customs_return_time' => $data_info['customs_return_time'],
            ];
        }
        return $this->save_data = $data_arr;
    }

    /**
     * 保存数据
     * @return [type] [description]
     */
    private function model_save(){
        $model = new HeyPayRecord();
        // var_dump($this->save_data);exit;
        if (isset($this->save_data['id'])) {
            $flag = $model->update($this->save_data);
        }else{
            $flag = $model->save($this->save_data);
        }

        // 将信息同步到订单
        $order_info = Order::where(['admin_id'=>$this->admin_id,'order_sn'=>$this->save_data['order_sn']])->find($this->save_data['order_id']);

        if ($order_info['pay_status'] != 'success') {
            $order_data = [];
            if (isset($this->save_data['record_status'])) {
                $order_data['pay_status'] = $this->save_data['record_status'];
            }
            if (isset($this->save_data['buyer_status'])) {
                $order_data['buyer_status'] = $this->save_data['buyer_status'];
            }
            if (!empty($order_data)) {
                $seflag = Order::where('id',$order_info['id'])->update($order_data);
            }
        }
        return $flag;
    }

    /**
     * 设置买家身份证验证
     * @param boolean $status [description]
     */
    private function set_buyer_status($status = true){
        if ($status) {
            $this->save_data['buyer_status'] = 'same'; 
        }else{
            $this->save_data['buyer_status'] = 'different';
        }
    }

    /**
     * 设置报关推送返回值
     * @param string $record_status   状态
     * @param string $response_code   返回值
     * @param string $response_msg    返回值描述
     * @param string $verify_depart   核验机构
     * @param string $depart_trade_no 核验机构流水号
     */
    private function set_response($record_status = 'success', $response_code = '', $response_msg = '', $extra = array()) {
        $this->errmsg = $response_msg;

        $this->save_data = array_merge($this->save_data, $extra);

        $this->save_data['response_code'] = $response_code;
        $this->save_data['response_msg'] = $response_msg;

        if (strtolower($record_status) == 'success') {
            $this->save_data['record_status'] = 'success';

        }elseif (strtolower($record_status) == 'failure') {
            $this->save_data['record_status'] = 'failure';

        }elseif (strtolower($record_status) == 'submitted') {
            $this->save_data['record_status'] = 'submitted';

        }elseif (strtolower($record_status) == 'processing') {
            $this->save_data['record_status'] = 'processing';
                
        }else{
            $this->save_data['record_status'] = 'except';

        }
    }

}
